package com.sp.config;

import com.sp.intercepted.JwtTokenInterceptor;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.convert.converter.Converter;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.List;

/**
 * WebMVC配置
 *
 * @author tong
 */
@Configuration
public class WebMVCConfigurer implements WebMvcConfigurer {

    @Autowired
    private JwtTokenInterceptor jwtTokenInterceptor;

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        //设置允许跨域的路径，允许所有路径
        registry.addMapping("/**")
                // 允许发送Cookie
                .allowCredentials(true)
                // 设置允许跨域请求的域名，允许所有源（通常不建议使用*，应该指定具体的源）
                .allowedOriginPatterns("http://localhost:*", "https://*.example.com")
                // 设置允许的请求方式
                .allowedMethods("GET", "POST", "PUT", "DELETE", "PATCH")
                // 设置允许的header属性
                .allowedHeaders("Origin", "Content-Type", "Accept", "Token")
                .allowedHeaders("*")
                // 暴露所有响应头
                .exposedHeaders("*");
    }

    /**
     * 扩展Spring MVC框架的消息转化器，定义时间格式转换器
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        //创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        //需要为消息转换器设置一个对象转换器，对象转换器可以将Java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        //将自己的消息转化器加入容器中，并且优先使用（因为有默认的，加在后面可能用不到）
        converters.add(0, converter);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // jwtTokenInterceptor拦截器在threadLocal里面放入用户信息
        registry.addInterceptor(jwtTokenInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns("/employees/login", "/employees/checkCode", "/employees/refreshToken");
    }

    /**
     * 处理时间戳
     */
    @Bean
    public Converter<String, LocalDateTime> localDateTimeConverter() {
        return new Converter<String, LocalDateTime>() {
            @Override
            public LocalDateTime convert(@NotNull String source) {
                if ("".equals(source)) {
                    return null;
                }
                return LocalDateTime.ofInstant(Instant.ofEpochMilli(Long.parseLong(source)), ZoneId.systemDefault());
            }
        };
    }

}
